<!DOCTYPE html>



  


<html class="theme-next mist use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Hexo, NexT" />










<meta property="og:type" content="website">
<meta property="og:title" content="kyssion-blog">
<meta property="og:url" content="http://yoursite.com/page/5/index.html">
<meta property="og:site_name" content="kyssion-blog">
<meta property="og:locale" content="zh-Hans">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="kyssion-blog">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Mist',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://yoursite.com/page/5/"/>





  <title>kyssion-blog</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left 
  page-home">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">kyssion-blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-schedule">
          <a href="/schedule/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-calendar"></i> <br />
            
            日程表
          </a>
        </li>
      
        
        <li class="menu-item menu-item-sitemap">
          <a href="/sitemap.xml" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-sitemap"></i> <br />
            
            站点地图
          </a>
        </li>
      
        
        <li class="menu-item menu-item-commonweal">
          <a href="/404/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br />
            
            公益404
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            
  <section id="posts" class="posts-expand">
    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/spring5-springMVC返回值和请求值预先处理/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/spring5-springMVC返回值和请求值预先处理/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <p>一般情况下，我们有的时候可能需要对web框架的返回值进行一定的处理，但是这种情况下有一定的局限性比如下面这种使用拦截器的情况</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ControllerReturnInterceptor</span> <span class="keyword">implements</span> <span class="title">HandlerInterceptor</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">postHandle</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">        System.out.println(handler);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>我们继承了HandlerUbterceotor 接口并且实现了postHandle 方法，这个方法将会在controller处理完之后将返回值放入handler中，通过这种方法我们可以对handler中的属性进行修改。</p>
<p>但是这样是有局限性的，首先我们无法封装handler 比如将返回的值换成另一个类，其次这个对象是object 我们需要强制转化才能使用，这样就有了一定的局限性。</p>
<p>正因为这样在spring4 添加了两个新的接口 RequestBodyAdvice和ResponseBodyAdvice</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">RequestBodyAdvice</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">boolean</span> <span class="title">supports</span><span class="params">(MethodParameter methodParameter, Type targetType,</span></span></span><br><span class="line"><span class="function"><span class="params">			Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; converterType)</span></span>;</span><br><span class="line"></span><br><span class="line">	<span class="function">HttpInputMessage <span class="title">beforeBodyRead</span><span class="params">(HttpInputMessage inputMessage, MethodParameter parameter,</span></span></span><br><span class="line"><span class="function"><span class="params">			Type targetType, Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; converterType)</span> <span class="keyword">throws</span> IOException</span>;</span><br><span class="line"></span><br><span class="line">	<span class="function">Object <span class="title">afterBodyRead</span><span class="params">(Object body, HttpInputMessage inputMessage, MethodParameter parameter,</span></span></span><br><span class="line"><span class="function"><span class="params">			Type targetType, Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; converterType)</span></span>;</span><br><span class="line"></span><br><span class="line">	<span class="function">Object <span class="title">handleEmptyBody</span><span class="params">(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter,</span></span></span><br><span class="line"><span class="function"><span class="params">			Type targetType, Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; converterType)</span></span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">ResponseBodyAdvice</span>&lt;<span class="title">T</span>&gt; </span>&#123;</span><br><span class="line"></span><br><span class="line">	<span class="function"><span class="keyword">boolean</span> <span class="title">supports</span><span class="params">(MethodParameter returnType, Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; converterType)</span></span>;</span><br><span class="line"></span><br><span class="line">	<span class="meta">@Nullable</span></span><br><span class="line">	<span class="function">T <span class="title">beforeBodyWrite</span><span class="params">(@Nullable T body, MethodParameter returnType, MediaType selectedContentType,</span></span></span><br><span class="line"><span class="function"><span class="params">			Class&lt;? extends HttpMessageConverter&lt;?&gt;&gt; selectedConverterType,</span></span></span><br><span class="line"><span class="function"><span class="params">			ServerHttpRequest request, ServerHttpResponse response)</span></span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>其中supports方法是为了判断是否可以执行处理逻辑，剩下的方法就封装恶劣在参数生成之前之后等操作步骤和拦截器相同，就不在多说了</p>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/spring5-导入资源文件/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/spring5-导入资源文件/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="spring5-导入资源文件"><a href="#spring5-导入资源文件" class="headerlink" title="spring5-导入资源文件"></a>spring5-导入资源文件</h2><p>一般情况下一些配置属性都是使用配置文件进行导入的，在一定的程度上进行了解藕，这里整理一下java 和spring框架在获取资源上的一些配配置</p>
<h3 id="java进行资源的配置"><a href="#java进行资源的配置" class="headerlink" title="java进行资源的配置"></a>java进行资源的配置</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> FileNotFoundException </span>&#123;</span><br><span class="line">        method();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//简单使用java进行配置文件的读取</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">method</span><span class="params">()</span></span>&#123;</span><br><span class="line">        Properties properties= <span class="keyword">new</span> Properties();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            properties.load(<span class="keyword">new</span> FileInputStream(Thread.currentThread().getContextClassLoader().getResource(<span class="string">"bean.properties"</span>).getPath()));</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        User user = <span class="keyword">new</span> User();</span><br><span class="line">        user.setName(properties.getProperty(<span class="string">"user.name"</span>));</span><br><span class="line">        user.setPassword(properties.getProperty(<span class="string">"user.password"</span>));</span><br><span class="line">        user.say();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>坑点</strong>：Thread.currentThread().getContextClassLoader() 可以获得项目编译后的执行根目录相当于 maven项目 的resource， 这一点非常重要</p>
<h3 id="使用spring的bean-xml配置文件导入相关的配置"><a href="#使用spring的bean-xml配置文件导入相关的配置" class="headerlink" title="使用spring的bean.xml配置文件导入相关的配置"></a>使用spring的bean.xml配置文件导入相关的配置</h3><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">       <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"propertyConfigurer"</span></span></span><br><span class="line"><span class="tag">          <span class="attr">class</span>=<span class="string">"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"locations"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">value</span>&gt;</span>classpath:bean.properties<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"user"</span> <span class="attr">class</span>=<span class="string">"org.demo.bean.User"</span> <span class="attr">scope</span>=<span class="string">"singleton"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"name"</span> <span class="attr">value</span>=<span class="string">"$&#123;user.name&#125;"</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">value</span>=<span class="string">"$&#123;user.password&#125;"</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="spring-增强配置文件处理使用注解进行相关的各种配置"><a href="#spring-增强配置文件处理使用注解进行相关的各种配置" class="headerlink" title="spring 增强配置文件处理使用注解进行相关的各种配置"></a>spring 增强配置文件处理使用注解进行相关的各种配置</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="meta">@PropertySource</span>(<span class="string">"classpath:bean.properties"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"$&#123;user.name&#125;"</span>)</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="meta">@Value</span>(<span class="string">"$&#123;user.password&#125;"</span>)</span><br><span class="line">    <span class="keyword">private</span> String password;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getPassword</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> password;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setPassword</span><span class="params">(String password)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.password = password;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">say</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="keyword">this</span>.name+<span class="string">" "</span>+<span class="keyword">this</span>.password);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>使用 java 的@value 和 PropertySource 注解结合使用</p>
<h3 id="springboot-导入资源文件增强"><a href="#springboot-导入资源文件增强" class="headerlink" title="springboot-导入资源文件增强"></a>springboot-导入资源文件增强</h3><p>spring boot 通过注解的方法将各种属性通过自动化的形式加载进javabean中，简化操作。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PropertySource</span>(&#123;<span class="string">"classpath:application.yaml"</span>,<span class="string">"classpath:application.properties"</span>&#125;)</span><br><span class="line"><span class="meta">@ConfigurationProperties</span>(prefix = <span class="string">"auther"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MydemoApplication</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> name;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.name = name;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">getPassword</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> password;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setPassword</span><span class="params">(String password)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.password = password;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="keyword">private</span> String name;</span><br><span class="line">	<span class="keyword">private</span> String password;</span><br><span class="line">	<span class="meta">@RequestMapping</span>(<span class="string">"/"</span>)</span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">say</span><span class="params">()</span></span>&#123;</span><br><span class="line">		System.out.println(<span class="keyword">this</span>.name+<span class="string">" :"</span>+<span class="keyword">this</span>.password);</span><br><span class="line">		<span class="keyword">return</span> <span class="keyword">this</span>.name+<span class="string">" :"</span>+<span class="keyword">this</span>.password;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">		SpringApplication.run(MydemoApplication.class, args);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>配置文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">auther.name=liyuelin</span><br><span class="line">auther.password=14159265jkl</span><br></pre></td></tr></table></figure>
<p>@ConfigurationProperties注解将会对 自动注入相关配置文件中的属性省去 前缀自动的注入到相关的配置文件中</p>
<p>升级版注解  @EnableConfigurationProperties(MyconfigProperties.class)  一般结合 @configuration注解使用    —-将指定的类似上面javabean的bean 自动完成属性注入功能</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@EnableConfigurationProperties</span>(MyconfigProperties.class)<span class="comment">//允许这个类进行自动转配并且导入配置文件属性</span></span><br><span class="line"><span class="meta">@EnableAspectJAutoProxy</span></span><br><span class="line"><span class="meta">@EnableAutoConfiguration</span></span><br><span class="line"><span class="meta">@ConfigurationProperties</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyconfigAutoConfig</span> </span>&#123;</span><br><span class="line"> </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/spring5-异步调用和定时器/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/spring5-异步调用和定时器/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h2 id="spring5-异步调用和定时器"><a href="#spring5-异步调用和定时器" class="headerlink" title="spring5-异步调用和定时器"></a>spring5-异步调用和定时器</h2><blockquote>
<p>Eable*类型的注解是和spring configurtion注解搭配使用的目的是减少配置和代码数量</p>
</blockquote>
<h3 id="EnableAsync-支持异步操作"><a href="#EnableAsync-支持异步操作" class="headerlink" title="@EnableAsync 支持异步操作"></a>@EnableAsync 支持异步操作</h3><blockquote>
<p>配置类 @EnableAsync</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ComponentScan</span>(basePackages = &#123;<span class="string">"org.bean"</span>, <span class="string">"org.controler"</span>&#125;)</span><br><span class="line"><span class="meta">@PropertySource</span>(<span class="string">"needpro.properties"</span>)</span><br><span class="line"><span class="meta">@EnableAsync</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringConfig</span> <span class="keyword">implements</span> <span class="title">AsyncConfigurer</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Executor <span class="title">getAsyncExecutor</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        ThreadPoolTaskExecutor taskExecutor = <span class="keyword">new</span> ThreadPoolTaskExecutor();</span><br><span class="line">        taskExecutor.setCorePoolSize(<span class="number">5</span>);</span><br><span class="line">        taskExecutor.setMaxPoolSize(<span class="number">10</span>);</span><br><span class="line">        taskExecutor.setQueueCapacity(<span class="number">25</span>);</span><br><span class="line">        taskExecutor.initialize();</span><br><span class="line">        <span class="keyword">return</span> taskExecutor;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> AsyncUncaughtExceptionHandler <span class="title">getAsyncUncaughtExceptionHandler</span><span class="params">()</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>javabean 类 @Async</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TaskExecutorConfig</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Async</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">execturonRunOne</span><span class="params">(<span class="keyword">int</span> a)</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"test one "</span>+a);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Thread.sleep(<span class="number">1000</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Async</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">executronRunTwo</span><span class="params">(<span class="keyword">int</span> b)</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"test two "</span>+b);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            Thread.sleep(<span class="number">1000</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (InterruptedException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>执行主函数</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        ApplicationContext context =<span class="keyword">new</span> AnnotationConfigApplicationContext(SpringConfig.class);</span><br><span class="line"> </span><br><span class="line">        TaskExecutorConfig taskExecutorConfig =</span><br><span class="line">                context.getBean(TaskExecutorConfig.class);</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> a=<span class="number">0</span>;a&lt;<span class="number">10</span>;a++)&#123;</span><br><span class="line">            taskExecutorConfig.execturonRunOne(a);</span><br><span class="line">            taskExecutorConfig.executronRunTwo(a);</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">"完成"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>结果：</p>
<p><img src="blogimg/spring/1.png" alt=""></p>
<p>结论：函数变成一部执行非阻塞型</p>
<h3 id="EnableScheduling-允许进行定时操作"><a href="#EnableScheduling-允许进行定时操作" class="headerlink" title="@EnableScheduling 允许进行定时操作"></a>@EnableScheduling 允许进行定时操作</h3><blockquote>
<p>配置类</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@EnableScheduling</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringConfig</span> <span class="keyword">implements</span> <span class="title">AsyncConfigurer</span> </span>&#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>javabean类</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.scheduling.annotation.Scheduled;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Service;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SchedyledIten</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Scheduled</span>(initialDelay =<span class="number">2000</span>,fixedDelay = <span class="number">2000</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">methodOne</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"one"</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Scheduled</span>(initialDelay =<span class="number">2000</span>,fixedRate = <span class="number">2000</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">method2</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"two"</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Scheduled</span>(initialDelay =<span class="number">2000</span>,cron = <span class="string">"0 0 2 1 * ?  "</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">method3</span><span class="params">()</span></span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"two"</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>注意</strong>：除了cron标记的其他元素如果没有使用iniiaDelay参数将会执行两边（调用一边，没有进行延迟一遍） ，cron表达式只支持六个参数</p>
<blockquote>
<p>cron 表达式详解</p>
</blockquote>
<table>
<thead>
<tr>
<th>符号</th>
<th>Seconds</th>
<th>Minutes</th>
<th>Hours</th>
<th>DayofMonth</th>
<th>Month</th>
<th>DayofWeek</th>
<th>Year</th>
</tr>
</thead>
<tbody>
<tr>
<td>，</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
</tr>
<tr>
<td>–</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
</tr>
<tr>
<td>*</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
</tr>
<tr>
<td>/</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
<td>Y</td>
</tr>
<tr>
<td>?</td>
<td>N</td>
<td>N</td>
<td>N</td>
<td>Y</td>
<td>N</td>
<td>Y</td>
<td>N</td>
</tr>
<tr>
<td>L</td>
<td>N</td>
<td>N</td>
<td>N</td>
<td>Y</td>
<td>N</td>
<td>Y</td>
<td>N</td>
</tr>
<tr>
<td>W</td>
<td>N</td>
<td>N</td>
<td>N</td>
<td>Y</td>
<td>N</td>
<td>N</td>
<td>N</td>
</tr>
<tr>
<td>C</td>
<td>N</td>
<td>N</td>
<td>N</td>
<td>Y</td>
<td>N</td>
<td>Y</td>
<td>N</td>
</tr>
<tr>
<td>#</td>
<td>N</td>
<td>N</td>
<td>N</td>
<td>N</td>
<td>N</td>
<td>Y</td>
<td>N</td>
</tr>
</tbody>
</table>
<ol>
<li><ul>
<li>：表示匹配该域的任意值，假如在Minutes域使用*, 即表示每分钟都会触发事件。</li>
</ul>
</li>
<li>? ：只能用在DayofMonth和DayofWeek两个域。它也匹配域的任意值，但实际不会。因为3. DayofMonth和DayofWeek会相互影响。例如想在每月的20日触发调度，不管20日到底是星期几，则只能使用如下写法： 13 13 15 20 <em> ?, 其中最后一位只能用？，而不能使用</em>，如果使用*表示不管星期几都会触发，实际上并不是这样。 </li>
<li>–  :表示范围，例如在Minutes域使用5-20，表示从5分到20分钟每分钟触发一次 </li>
<li>/  ：表示起始时间开始触发，然后每隔固定时间触发一次，例如在Minutes域使用5/20,则意味着5分钟触发一次，而25，45等分别触发一次. </li>
<li>,  ：表示列出枚举值值。例如：在Minutes域使用5,20，则意味着在5和20分每分钟触发一次。 </li>
<li>L ：表示最后，只能出现在DayofWeek和DayofMonth域，如果在DayofWeek域使用5L,意味着在最后的一个星期四触发。 </li>
<li>W ：表示有效工作日(周一到周五),只能出现在DayofMonth域，系统将在离指定日期的最近的有效工作日触发事件。例如：在 DayofMonth使用5W，如果5日是星期六，则将在最近的工作日：星期五，即4日触发。如果5日是星期天，则在6日(周一)触发；如果5日在星期一到星期五中的一天，则就在5日触发。另外一点，W的最近寻找不会跨过月份 </li>
<li>LW ：这两个字符可以连用，表示在某个月最后一个工作日，即最后一个星期五。 </li>
<li># ：用于确定每个月第几个星期几，只能出现在DayofMonth域。例如在4#2，表示某月的第二个星期三。</li>
</ol>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/spring5-数据库支持/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/spring5-数据库支持/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h3 id="JdbcTemplate-spring-数据库操作基础类"><a href="#JdbcTemplate-spring-数据库操作基础类" class="headerlink" title="JdbcTemplate spring 数据库操作基础类"></a>JdbcTemplate spring 数据库操作基础类</h3><p>这个类是spring进行jdbc操作的核心，通过这个方法将节省数据库操作，和避免一些低级错误，比如资源没哟释放等等</p>
<h4 id="select-操作"><a href="#select-操作" class="headerlink" title="select 操作"></a>select 操作</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//指定返回数据的类型</span></span><br><span class="line"><span class="keyword">int</span> rowCount = <span class="keyword">this</span>.jdbcTemplate.queryForObject(<span class="string">"select count(*) from t_actor"</span>, Integer.class);</span><br><span class="line"><span class="comment">//传入参数 和指定返回的类型   注意 最后一个参数是数组</span></span><br><span class="line"><span class="keyword">int</span> countOfActorsNamedJoe = <span class="keyword">this</span>.jdbcTemplate.queryForObject(</span><br><span class="line">        <span class="string">"select count(*) from t_actor where first_name = ?"</span>, Integer.class, <span class="string">"Joe"</span>);</span><br><span class="line"><span class="comment">//另一种写法  中间的数组是</span></span><br><span class="line">String lastName = <span class="keyword">this</span>.jdbcTemplate.queryForObject(</span><br><span class="line">        <span class="string">"select last_name from t_actor where id = ?"</span>,</span><br><span class="line">        <span class="keyword">new</span> Object[]&#123;<span class="number">1212L</span>&#125;, String.class);</span><br><span class="line"><span class="comment">// 使用 RowMapper 接口处理返回的数据 (或者使用ResultSetExtractor)</span></span><br><span class="line">Actor actor = <span class="keyword">this</span>.jdbcTemplate.queryForObject(</span><br><span class="line">        <span class="string">"select first_name, last_name from t_actor where id = ?"</span>,</span><br><span class="line">        <span class="keyword">new</span> Object[]&#123;<span class="number">1212L</span>&#125;,</span><br><span class="line">        <span class="keyword">new</span> RowMapper&lt;Actor&gt;() &#123;</span><br><span class="line">            <span class="function"><span class="keyword">public</span> Actor <span class="title">mapRow</span><span class="params">(ResultSet rs, <span class="keyword">int</span> rowNum)</span> <span class="keyword">throws</span> SQLException </span>&#123;</span><br><span class="line">                Actor actor = <span class="keyword">new</span> Actor();</span><br><span class="line">                actor.setFirstName(rs.getString(<span class="string">"first_name"</span>));</span><br><span class="line">                actor.setLastName(rs.getString(<span class="string">"last_name"</span>));</span><br><span class="line">                <span class="keyword">return</span> actor;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br></pre></td></tr></table></figure>
<h4 id="update-delete-insert操作"><a href="#update-delete-insert操作" class="headerlink" title="update delete insert操作"></a>update delete insert操作</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">jdbcTemplate.update(</span><br><span class="line">        <span class="string">"insert into t_actor (first_name, last_name) values (?, ?)"</span>,</span><br><span class="line">        <span class="string">"Leonor"</span>, <span class="string">"Watling"</span>);</span><br><span class="line">jdbcTemplate.update(</span><br><span class="line">        <span class="string">"update t_actor set last_name = ? where id = ?"</span>,</span><br><span class="line">        <span class="string">"Banjo"</span>, <span class="number">5276L</span>);</span><br><span class="line">jdbcTemplate.update(</span><br><span class="line">        <span class="string">"delete from actor where id = ?"</span>,</span><br><span class="line">        Long.valueOf(actorId));</span><br><span class="line">jdbcTemplate.update(</span><br><span class="line">        <span class="string">"delete from actor where id = ?"</span>,</span><br><span class="line">        <span class="keyword">new</span> Object[<span class="string">"sdfsdf"</span>],);    </span><br><span class="line">jdbcTemplate.update(<span class="string">"udpate TABLE set NAME = ?"</span></span><br><span class="line">        ,<span class="keyword">new</span> Object[]&#123;<span class="string">"tom"</span>&#125;,<span class="keyword">new</span> <span class="keyword">int</span>[]&#123;Types.VARCHAR&#125;);</span><br></pre></td></tr></table></figure>
<h4 id="使用数据操作语句进行操作的通用方法"><a href="#使用数据操作语句进行操作的通用方法" class="headerlink" title="使用数据操作语句进行操作的通用方法"></a>使用数据操作语句进行操作的通用方法</h4><p>这个方法可以执行任何语句</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">jdbcTemplate.execute(<span class="string">"create table mytable (id integer, name varchar(100))"</span>);</span><br></pre></td></tr></table></figure>
<h4 id="jdbcTemple-初始化"><a href="#jdbcTemple-初始化" class="headerlink" title="jdbcTemple 初始化"></a>jdbcTemple 初始化</h4><p>传入一个数据库链接的相关信息和是否使用延迟加载的方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">JdbcTemplate template = <span class="keyword">new</span> JdbcTemplate(database,lazyinit);</span><br></pre></td></tr></table></figure>
<h3 id="NamedParameterJdbcTemplate"><a href="#NamedParameterJdbcTemplate" class="headerlink" title="NamedParameterJdbcTemplate"></a>NamedParameterJdbcTemplate</h3><p>这个接口是一个特殊的存在，底层使用JDBCTemplate同时将之前使用适配符的？进行了替换</p>
<p>这个接口的一个高级应用就是使用 SqlParameterSource 进行分装 ， spring 官方文档中主要提供了如下的三种方法进行相关的操作</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> NamedParameterJdbcTemplate namedParameterJdbcTemplate;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setDataSource</span><span class="params">(DataSource dataSource)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.namedParameterJdbcTemplate = <span class="keyword">new</span> NamedParameterJdbcTemplate(dataSource);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//使用类似hashmap的方法进行相关的操作</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countOfActorsByFirstName</span><span class="params">(String firstName)</span> </span>&#123;</span><br><span class="line">    String sql = <span class="string">"select count(*) from T_ACTOR where first_name = :first_name"</span>;</span><br><span class="line">    SqlParameterSource namedParameters = <span class="keyword">new</span> MapSqlParameterSource(<span class="string">"first_name"</span>, firstName);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用最一般的map进行操作</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countOfActorsByFirstName</span><span class="params">(String firstName)</span> </span>&#123;</span><br><span class="line">    String sql = <span class="string">"select count(*) from T_ACTOR where first_name = :first_name"</span>;</span><br><span class="line">    Map&lt;String, String&gt; namedParameters = Collections.singletonMap(<span class="string">"first_name"</span>, firstName);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.namedParameterJdbcTemplate.queryForObject(sql, namedParameters,  Integer.class);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 直接封装相关的各</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">countOfActors</span><span class="params">(Actor exampleActor)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// notice how the named parameters match the properties of the above 'Actor' class</span></span><br><span class="line">    String sql = <span class="string">"select count(*) from T_ACTOR where first_name = :firstName and last_name = :lastName"</span>;</span><br><span class="line">    SqlParameterSource namedParameters = <span class="keyword">new</span> BeanPropertySqlParameterSource(exampleActor);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.namedParameterJdbcTemplate.queryForObject(sql, namedParameters, Integer.class);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="DriverManagerDataSource-spring-内置数据库的实现"><a href="#DriverManagerDataSource-spring-内置数据库的实现" class="headerlink" title="DriverManagerDataSource spring 内置数据库的实现"></a>DriverManagerDataSource spring 内置数据库的实现</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">DriverManagerDataSource dataSource = <span class="keyword">new</span> DriverManagerDataSource();</span><br><span class="line">dataSource.setDriverClassName(<span class="string">"org.hsqldb.jdbcDriver"</span>);</span><br><span class="line">dataSource.setUrl(<span class="string">"jdbc:hsqldb:hsql://localhost:"</span>);</span><br><span class="line">dataSource.setUsername(<span class="string">"sa"</span>);</span><br><span class="line">dataSource.setPassword(<span class="string">""</span>);</span><br></pre></td></tr></table></figure>
<h3 id="spring-进行批处理"><a href="#spring-进行批处理" class="headerlink" title="spring 进行批处理"></a>spring 进行批处理</h3><p>使用JDBCTemplete进行批处理</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JdbcActorDao</span> <span class="keyword">implements</span> <span class="title">ActorDao</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> JdbcTemplate jdbcTemplate;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setDataSource</span><span class="params">(DataSource dataSource)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.jdbcTemplate = <span class="keyword">new</span> JdbcTemplate(dataSource);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">int</span>[] batchUpdate(<span class="keyword">final</span> List&lt;Actor&gt; actors) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.jdbcTemplate.batchUpdate(</span><br><span class="line">                <span class="string">"update t_actor set first_name = ?, last_name = ? where id = ?"</span>,</span><br><span class="line">                <span class="keyword">new</span> BatchPreparedStatementSetter() &#123;</span><br><span class="line">                    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setValues</span><span class="params">(PreparedStatement ps, <span class="keyword">int</span> i)</span> <span class="keyword">throws</span> SQLException </span>&#123;</span><br><span class="line">                        ps.setString(<span class="number">1</span>, actors.get(i).getFirstName());</span><br><span class="line">                        ps.setString(<span class="number">2</span>, actors.get(i).getLastName());</span><br><span class="line">                        ps.setLong(<span class="number">3</span>, actors.get(i).getId().longValue());</span><br><span class="line">                    &#125;</span><br><span class="line">                    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getBatchSize</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                        <span class="keyword">return</span> actors.size();</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// ... additional methods</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>使用namedParameterJdbcTemplate 进行批处理</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JdbcActorDao</span> <span class="keyword">implements</span> <span class="title">ActorDao</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> NamedParameterTemplate namedParameterJdbcTemplate</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setDataSource</span><span class="params">(DataSource dataSource)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.namedParameterJdbcTemplate = <span class="keyword">new</span> NamedParameterJdbcTemplate(dataSource);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">int</span>[] batchUpdate(List&lt;Actor&gt; actors) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.namedParameterJdbcTemplate.batchUpdate(</span><br><span class="line">                <span class="string">"update t_actor set first_name = :firstName, last_name = :lastName where id = :id"</span>,</span><br><span class="line">                SqlParameterSourceUtils.createBatch(actors));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// ... additional methods</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>结语： 这里的这些特性其实就是在使用相关的技术的时候感兴趣才看的，真正在生产环境下使用 mybatis这种持久层框架比较多</p>
</blockquote>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/java-一些基本知识点整理/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/java-一些基本知识点整理/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <blockquote>
<p>学习java一定的时间了，这里一些知识点的整理</p>
</blockquote>
<h2 id="变量必须是字母-下划线或者-符开头不能是-java-关键字变量命名规范-驼峰写法-类首字母大写驼峰写法"><a href="#变量必须是字母-下划线或者-符开头不能是-java-关键字变量命名规范-驼峰写法-类首字母大写驼峰写法" class="headerlink" title="变量必须是字母,下划线或者$符开头不能是 java 关键字变量命名规范 驼峰写法,类首字母大写驼峰写法"></a>变量必须是字母,下划线或者$符开头不能是 java 关键字变量命名规范 驼峰写法,类首字母大写驼峰写法</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> $a = <span class="number">123</span>;</span><br><span class="line"><span class="keyword">int</span> _b = <span class="number">123</span>;</span><br></pre></td></tr></table></figure>
<h2 id="基本数据类型"><a href="#基本数据类型" class="headerlink" title="基本数据类型"></a>基本数据类型</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//变量的形成分为两个步骤声明和初始化</span></span><br><span class="line">变量只是一个声明的存储单元而已</span><br><span class="line"><span class="keyword">int</span> aa, bbb, ccc;</span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="number">1</span>.<span class="keyword">byte</span> <span class="number">1</span>字节 <span class="keyword">short</span></span><br><span class="line"><span class="number">2</span>字节 <span class="keyword">int</span> <span class="number">4</span>字节 <span class="keyword">long</span></span><br><span class="line"><span class="number">8</span>字节 <span class="keyword">float</span></span><br><span class="line"><span class="keyword">double</span> <span class="keyword">boolean</span> <span class="keyword">char</span></span><br><span class="line">Integer.toBinaryString($a);<span class="comment">// 转化为二进制字符串</span></span><br><span class="line"><span class="keyword">long</span> c = <span class="number">1234L</span>;<span class="comment">// 显示声明长整型</span></span><br><span class="line"><span class="comment">// 进转化问题</span></span><br><span class="line"><span class="keyword">int</span> d = <span class="number">0123</span>;<span class="comment">// 使用 8进制</span></span><br><span class="line">d = <span class="number">0x1234</span>;<span class="comment">// 使用16进制</span></span><br><span class="line">d = <span class="number">0b1000_0000</span>;<span class="comment">//</span></span><br><span class="line">j7新特心直接进行</span><br><span class="line">二进制编写</span><br></pre></td></tr></table></figure>
<h2 id="java-运算符"><a href="#java-运算符" class="headerlink" title="java 运算符"></a>java 运算符</h2><p><strong>赋值运算符</strong> : =<br><strong>关系运算符</strong> : &gt; , &lt; , &gt;= , &lt;= , == , != , instanceof<br><strong>逻辑运算符</strong> : &amp;&amp; , || , !<br><strong>位运算符</strong> : &amp; , | , ^异或 , ~非 , &gt;&gt; , &lt;&lt; , &gt;&gt;&gt;<br><strong>条件运算符</strong>: ? :<br><strong>扩展赋值运算符</strong> : += , -= , *= , /=</p>
<h1 id="流程控制语句"><a href="#流程控制语句" class="headerlink" title="流程控制语句"></a>流程控制语句</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line"> </span><br><span class="line">&#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line"> </span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> </span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">while</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 先运行在判断---这个方法相当于给代码块进行命名而已</span></span><br><span class="line">hhe: <span class="keyword">do</span> &#123;</span><br><span class="line"><span class="keyword">break</span> hhe;</span><br><span class="line"><span class="comment">// continue hhe;//表示跳出一定的循环结构</span></span><br><span class="line">&#125; <span class="keyword">while</span> (<span class="keyword">true</span>);</span><br><span class="line"><span class="comment">// jdk7 增强型switch控制语句 可用int 枚举类型和字符串</span></span><br><span class="line">String string = <span class="string">"sdf"</span>;<span class="comment">//如果不添加break switch会将之后所有的对象都当成自己代码快中的东西会忽略case 一直执行下去</span></span><br><span class="line"><span class="keyword">switch</span> (string) &#123;</span><br><span class="line"><span class="keyword">case</span> <span class="string">"ggg"</span>:</span><br><span class="line">System.out.println(<span class="string">"One.main()"</span>);</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line"><span class="keyword">default</span>:</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">while</span> (<span class="keyword">true</span>) &#123;</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="基础方法-scanner"><a href="#基础方法-scanner" class="headerlink" title="基础方法 scanner"></a>基础方法 scanner</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SuppressWarnings</span>(<span class="string">"resource"</span>)</span><br><span class="line">Scanner scanner = <span class="keyword">new</span> Scanner(System.in);<span class="comment">// 传入一个输入流</span></span><br><span class="line"><span class="comment">// 引申可以从字符串（Readable）、输入流、文件等等来直接构建Scanner对象，有了Scanner了，</span></span><br><span class="line"><span class="comment">// 就可以逐段（根据正则分隔式）来扫描整个文本，并对扫描后的结果做想要的处理。</span></span><br><span class="line">String line = scanner.nextLine(); <span class="comment">// 获得控制台输入的下一行</span></span><br><span class="line">scanner.useDelimiter(<span class="string">"|,|\\."</span>); <span class="comment">//以指定的字符记性分割字符串</span></span><br><span class="line">scanner.delimiter(); <span class="comment">//返回此 Scanner 当前正在用于匹配分隔符的 Pattern。</span></span><br><span class="line">scanner.hasNext() ; <span class="comment">//判断扫描器中当前扫描位置后是否还存在下一段。（原APIDoc的注释很扯淡）</span></span><br><span class="line">scanner.hasNextLine(); <span class="comment">//如果在此扫描器的输入中存在另一行，则返回 true。</span></span><br><span class="line">scanner.next(); <span class="comment">//查找并返回来自此扫描器的下一个完整标记。</span></span><br><span class="line">scanner.nextLine(); <span class="comment">//此扫描器执行当前行，并返回跳过的输入信息。</span></span><br><span class="line"><span class="comment">//java 比较运算符 -- 只能用来比较有继承关系的类</span></span><br><span class="line">Integer bb=<span class="number">12</span>;</span><br><span class="line"><span class="comment">//这个是对象比较符</span></span><br><span class="line"><span class="keyword">if</span> (bb <span class="keyword">instanceof</span> Integer) &#123;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//使用类名称比较符</span></span><br><span class="line">Integer.class.isInstance(bb);</span><br></pre></td></tr></table></figure>
<h2 id="枚举类型-简单枚举类型"><a href="#枚举类型-简单枚举类型" class="headerlink" title="枚举类型 简单枚举类型"></a>枚举类型 简单枚举类型</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> Color &#123;</span><br><span class="line">RED, GREEN, BLANK, YELLOW</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 可以在内部声明方法</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> Light &#123;</span><br><span class="line"><span class="comment">// 利用构造函数传参---枚举类型中每一个参数就相当于一个枚举类型</span></span><br><span class="line">RED(<span class="number">1</span>), GREEN(<span class="number">3</span>), YELLOW(<span class="number">2</span>);</span><br><span class="line"><span class="comment">// 定义私有变量</span></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">int</span> nCode;</span><br><span class="line"><span class="comment">// 构造函数，枚举类型只能为私有</span></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="title">Light</span><span class="params">(<span class="keyword">int</span> _nCode)</span> </span>&#123;</span><br><span class="line"><span class="keyword">this</span>.nCode = _nCode;</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>&#123;</span><br><span class="line"><span class="keyword">return</span> String.valueOf(<span class="keyword">this</span>.nCode);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="Java包注释"><a href="#Java包注释" class="headerlink" title="Java包注释"></a>Java包注释</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@author</span> 作者</span><br><span class="line"><span class="meta">@version</span> 版本</span><br><span class="line"><span class="meta">@param</span> 参数</span><br><span class="line"><span class="meta">@return</span> 返回值</span><br><span class="line"><span class="meta">@throws</span> 异常</span><br><span class="line"><span class="meta">@deprecated</span> 废弃</span><br></pre></td></tr></table></figure>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/java-从源代码分析javaNIO的运行过程(一)/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/java-从源代码分析javaNIO的运行过程(一)/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h3 id="这一节解析一下-java-NIO中-ServerSocketChannel创建的过程"><a href="#这一节解析一下-java-NIO中-ServerSocketChannel创建的过程" class="headerlink" title="这一节解析一下 java NIO中 ServerSocketChannel创建的过程"></a>这一节解析一下 java NIO中 ServerSocketChannel创建的过程</h3><blockquote>
<p>channel  在java中表示通道，是用来进行数据的有效传输</p>
</blockquote>
<p>广义上来说通道可以被分为两类：<strong>File I/O和Stream I/O，也就是文件通道和套接字通道</strong></p>
<p>如果分的更细致一点则是：</p>
<ul>
<li>FileChannel 从文件读写数据</li>
<li>SocketChannel 通过TCP读写网络数据</li>
<li>ServerSocketChannel 可以监听新进来的TCP连接，并对每个链接创建对应的SocketChannel</li>
<li>DatagramChannel 通过UDP读写网络中的数据</li>
<li>Pipe</li>
</ul>
<p>通道既可以是单向的也可以是双向的。只实现ReadableByteChannel接口中的read()方法或者只实现WriteableByteChannel接口中的write()方法的通道皆为单向通道，同时实现ReadableByteChannel和WriteableByteChannel为双向通道，比如ByteChannel。对于socket通道来说，它们一直是双向的，而对于FileChannel来说，它同样实现了ByteChannel，但是我们知道<strong>通过FileInputStream的getChannel（）获取的FileChannel只具有文件的只读权限</strong>，那此时的在该通道调用write（）会出现什么情况？不出意外的抛出了NonWriteChannelException异常。<br>通过以上，我们得出结论：<strong>通道都与特定的I/O服务挂钩，并且通道的性能受限于所连接的I/O服务的性质。</strong></p>
<p>通道的工作模式有两种：阻塞或非阻塞。在非阻塞模式下，调用的线程不会休眠，请求的操作会立刻返回结果；在阻塞模式下，调用的线程会产生休眠。<strong>另外除FileChannel不能运行在非阻塞模式下，其余的通道都可阻塞运行也可以以非阻塞的方式运行。</strong></p>
<p>另外从SelectableChannel引申出的类可以和支持有条件选择的Selector结合使用，进而充分利用多路复用的I/O（multiplexed I/O）来提高性能.对于Socket通道类来说，通常与Selector共同使用以提高性能。需要<strong>注意的是通道不能被重复使用，一个打开的通道代表着与一个特定I/O服务进行连接并封装了该连接的状态，通道一旦关闭，该连接便会断开。</strong>通道的close（）比较特殊，无论在通道时在阻塞模式下还是非阻塞模式下，由于close（）方法的调用而导致底层I/O的关闭都可能会造成线程的暂时阻塞。在一个已关闭的通道上调用close（）并没有任何意义，只会立即返回。</p>
<h3 id="现在进入正题，讨论一下ServerSocketChannel"><a href="#现在进入正题，讨论一下ServerSocketChannel" class="headerlink" title="现在进入正题，讨论一下ServerSocketChannel"></a>现在进入正题，讨论一下ServerSocketChannel</h3><p>Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 类似ServerSocket一样。要注意的是和DatagramChannel和SocketChannel不同，ServerSocketChannel本身不具备传输数据的能力，而只是负责监听传入的连接和创建新的SocketChannel。</p>
<p><img src="/blogimg/nio/1.png" alt=""></p>
<h4 id="创建一个ServerSocket很简单，代码如下"><a href="#创建一个ServerSocket很简单，代码如下" class="headerlink" title="创建一个ServerSocket很简单，代码如下"></a>创建一个ServerSocket很简单，代码如下</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ServerSocketChannel channel= ServerSocketChannel.open();</span><br></pre></td></tr></table></figure>
<h4 id="深入研究一下，-进入ServerSocketChannel的open方法"><a href="#深入研究一下，-进入ServerSocketChannel的open方法" class="headerlink" title="深入研究一下， 进入ServerSocketChannel的open方法"></a>深入研究一下， 进入ServerSocketChannel的open方法</h4><blockquote>
<p>ServerSocketChannel类 open方法</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> ServerSocketChannel <span class="title">open</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">	<span class="keyword">return</span> SelectorProvider.provider().openServerSocketChannel();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里首先将会调用SelectorProvider的provider方法,这一局将会返回一个SelectorProvider实例,主要作用就是使用spi或者-Dxxx参数传入的SelectorProvider的类url地址（类的包名加类名）返回一个imp实例</p>
<blockquote>
<p>SelectorProvider类  provider() 方法</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> SelectorProvider <span class="title">provider</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="keyword">synchronized</span> (lock) &#123;</span><br><span class="line">        <span class="keyword">if</span> (provider != <span class="keyword">null</span>)</span><br><span class="line">           <span class="keyword">return</span> provider;</span><br><span class="line">        <span class="keyword">return</span> AccessController.doPrivileged(</span><br><span class="line">            <span class="keyword">new</span> PrivilegedAction&lt;SelectorProvider&gt;() &#123;</span><br><span class="line">                <span class="function"><span class="keyword">public</span> SelectorProvider <span class="title">run</span><span class="params">()</span> </span>&#123;</span><br><span class="line">                        <span class="keyword">if</span> (loadProviderFromProperty())</span><br><span class="line">                            <span class="keyword">return</span> provider;</span><br><span class="line">                        <span class="keyword">if</span> (loadProviderAsService())</span><br><span class="line">                            <span class="keyword">return</span> provider;</span><br><span class="line">                        provider = sun.nio.ch.DefaultSelectorProvider.create();</span><br><span class="line">                        <span class="keyword">return</span> provider;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>然后会调用实例的 openServerSocketChannel()方法</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> ServerSocketChannel <span class="title">openServerSocketChannel</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> ServerSocketChannelImpl(<span class="keyword">this</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这个方法将会真正的返回一个ServerSocketChannelImpl实例，这个类一般就是由虚拟机的厂商提供的，这里就不进行深入的研究了</p>
<h3 id="最后看一下这个serversocketchannel个人觉得有用的方法"><a href="#最后看一下这个serversocketchannel个人觉得有用的方法" class="headerlink" title="最后看一下这个serversocketchannel个人觉得有用的方法"></a>最后看一下这个serversocketchannel个人觉得有用的方法</h3><ol>
<li><strong>public static ServerSocketChannel open() throws IOException</strong> 开启一个serversocketchannel</li>
<li><strong>public final int validOps()</strong>：返回这个通道支持的SelectionKey值，应为这个通道只是开启一个SocketChannel并没有信息交换的功能，只是监听功能，所有只能返回SelectionKey.OP_ACCEPT</li>
<li><strong>public final ServerSocketChannel bind(SocketAddress local)和public final ServerSocketChannel bind(SocketAddress local，int backlog)</strong>：字如其意将一个套接字和本地地址链接，有一个重构方法提供最大链接数支持</li>
<li><strong>public ServerSocket socket()</strong>：返回一个ServerSocket </li>
<li><strong>public SocketChannel accept() throws IOException</strong>：和传统的网络编程相同，如果使用的Nio那么将会立即的返回null否则将会阻塞住直到有链接建立</li>
<li><strong>public SocketAddress getLocalAddress() throws IOException</strong>：返回这里绑定的地址</li>
<li><strong>public final SelectableChannel configureBlocking(boolean block) throws IOException</strong>: 指定这个接口是阻塞的还是非阻塞的</li>
</ol>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/spring5-condition注解实现bean细致控制/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/spring5-condition注解实现bean细致控制/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/java-从AccessController.doPrivileged看java的授权和沙箱/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/java-从AccessController.doPrivileged看java的授权和沙箱/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <blockquote>
<p>这里主要是介绍java以代码为核心的授权方法(还有基于用户的jaas授权方法不做讨论),这个还是比较重要的(其实是看很多源代码框架使用了这个方法,为了保证代码在沙盒环境中可以运行).</p>
</blockquote>
<h3 id="权限"><a href="#权限" class="headerlink" title="权限"></a>权限</h3><p>在Java平台安全体系结构中，所有访问权限都是类型化的并且有层次结构，其根是抽象类 java.security.Permission 。标准的权限类大约有如下的这些(使用类来标记权限)</p>
<table>
<thead>
<tr>
<th>　</th>
<th>类型</th>
<th>权限名</th>
<th>操作</th>
<th>例子</th>
</tr>
</thead>
<tbody>
<tr>
<td>文件权限</td>
<td>java.io.FilePermission</td>
<td>文件名（平台依赖）</td>
<td>读、写、删除、执行</td>
<td>允许所有问价的读写删除执行：permission java.io.FilePermission “&lt;&lt; ALL FILES&gt;&gt;”, “read,write,delete,execute”;。允许对用户主目录的读：permission java.io.FilePermission “${user.home}/-“, “read”;。</td>
</tr>
<tr>
<td>套接字权限</td>
<td>java.net.SocketPermission</td>
<td>主机名:端口</td>
<td>接收、监听、连接、解析</td>
<td>允许实现所有套接字操作：permission java.net.SocketPermission “<em>:1-“, “accept,listen,connect,resolve”;。允许建立到特定网站的连接：permission java.net.SocketPermission “</em>.abc.com:1-“, “connect,resolve”;。</td>
</tr>
<tr>
<td>属性权限</td>
<td>java.util.PropertyPermission</td>
<td>需要访问的jvm属性名</td>
<td>读、写</td>
<td>读标准Java属性：permission java.util.PropertyPermission “java.<em>“, “read”;。在sdo包中创建属性：permission java.util.PropertyPermission “sdo.</em>“, “read,write”;。</td>
</tr>
<tr>
<td>运行时权限</td>
<td>java.lang.RuntimePermission</td>
<td>多种权限名[见附录A]</td>
<td>无</td>
<td>允许代码初始化打印任务：permission java.lang.RuntimePermission “queuePrintJob”</td>
</tr>
<tr>
<td>AWT权限</td>
<td>java.awt.AWTPermission</td>
<td>6种权限名[见附录B]</td>
<td>无</td>
<td>允许代码充分使用robot类：permission java.awt.AWTPermission “createRobot”; permission java.awt.AWTPermission “readDisplayPixels”;。</td>
</tr>
<tr>
<td>网络权限</td>
<td>java.net.NetPermission</td>
<td>3种权限名[见附录C]</td>
<td>无</td>
<td>允许安装流处理器：permission java.net.NetPermission “specifyStreamHandler”;。</td>
</tr>
<tr>
<td>安全权限</td>
<td>java.security.SecurityPermission</td>
<td>多种权限名[见附录D]</td>
<td>无</td>
<td></td>
</tr>
<tr>
<td>序列化权限</td>
<td>java.io.SerializablePermission</td>
<td>2种权限名[见附录E]</td>
<td>无</td>
<td></td>
</tr>
<tr>
<td>反射权限</td>
<td>java.lang.reflect.ReflectPermission</td>
<td>suppressAccessChecks（允许利用反射检查任意类的私有变量）</td>
<td>无</td>
<td></td>
</tr>
<tr>
<td>完全权限</td>
<td>java.security.AllPermission</td>
<td>无（拥有执行任何操作的权限）</td>
<td>无</td>
</tr>
</tbody>
</table>
<blockquote>
<p>在这种模式下 jvm的权限是给代码的(可以说类反正就代码的),一个类(代码)可以有多个权限(在$JREHOME/lib/security/java.policy文件中进行配置下面说),使用PermissionCollection这样的类进行封装(jvm在运行的时候通过文件自动生成好了,然后通过反射进行校验这些东西都被隐藏起来了,研究下去意义不大,就没有接着研究)</p>
</blockquote>
<h3 id="保护域和代码源"><a href="#保护域和代码源" class="headerlink" title="保护域和代码源"></a>保护域和代码源</h3><blockquote>
<p>java2 是针对代码(对象类)添加保护区,有一个内部类ProtectionDomain,通过这个类授权访问权限,如果多个类使用同一个ProtectionDomain将会认为这个权限是相同的</p>
</blockquote>
<blockquote>
<p>显然，一定要能惟一地标识一段运行代码以保证它的访问权限没有冲突。运行代码的惟一标识属性共有两项：代码的来源（代码装载到内存所用的 URL）和代码的 signer 实体（由对应于运行代码的数字签名的一组公共密钥指定）。这两种特性的组合在 Java 2 平台安全体系结构中编写为给定运行代码的 CodeSource (在ProtectionDomain内部可以看见这个对象)。</p>
</blockquote>
<h3 id="权限生成的具体过程"><a href="#权限生成的具体过程" class="headerlink" title="权限生成的具体过程"></a>权限生成的具体过程</h3><ol>
<li>Java 运行时通过名为 java.security.Policy 的类（的具体扩展）设置 ProtectionDomain 与授予它的权限之间的映射。</li>
<li>这个类的默认扩展是 sun.security.provider.PolicyFile 。正如其名字所表明的， sun.security.provider.PolicyFile 从一个文件中获得 CodeSource （由位置 URL 和 signer 标识别名）与授予它的权限之间的映射。</li>
<li>可以通过环境变量 java.security.policy 将这个文件的位置作为输入提供给 JVM。 Policy 类提供了一个名为 getPermissions() 的方法，可以调用它以获得授予特定 CodeSource 的一组权限。</li>
</ol>
<h3 id="权限加载的过程"><a href="#权限加载的过程" class="headerlink" title="权限加载的过程"></a>权限加载的过程</h3><ol>
<li>一个类与 其 ProtectionDomain 之间的映射是在类第一次装载时设置的，并在类被垃圾收集之前不会改变。</li>
<li>一个类通常是由一个名为 SecureClassLoader 的特殊类装载的。 SecureClassLoader 首先从相应 URL 处装载字节，如果需要还会验证包围文档文件的数字签名。然后它调用上述 getPermissions() 方法获得授予类的 CodeSource 的一个填充了静态绑定权限的异类 PermissionCollection 。</li>
<li>然后 SecureClassLoader 创建新的 ProtectionDomain ，传递 CodeSource 及其相关的权限作为其构造函数的参数（当然，这假定对于给定 CodeSource 还不存在 ProtectionDomain 。如果用一个现有的 CodeSource 装载类，那么就会重复使用它已经建立的 ProtectionDomain ） 。 </li>
<li>最后，用装载的类字节向 JVM 定义一个类，并在关联的 ProtectionDomain 中维护一个引用指针。</li>
</ol>
<h3 id="执行过程"><a href="#执行过程" class="headerlink" title="执行过程"></a>执行过程</h3><p>一个名为 SecurityManager 的类负责实施系统安全策略。在默认情况下不安装安全管理器，必须通过一个在启动时传递给 JVM 的、名为 java.security.manager 的环境变量显式地指定。任何应用程序都可找到安装的 SecurityManager 并调用它相应的 check<xxx> 方法。如果所要求的权限在给定运行时上下文中是授予的，那么调用将无声地返回。如果权限没有授予，那么将抛出一个 java.security.AccessControlException 。</xxx></p>
<p>Java 2 平台安全体系结构通过引入一个名为 AccessController 的新类使这一切变得简单了，并更具有可扩展性。这个类的目的与 SecurityManager 是一样的，即它负责做出访问决定。当然， 为了向后兼容性保留了 SecurityManager 类，但是其更新的实现委派给了底层的 AccessController 。对 SecurityManager 类进行的所有 check<xxx> 方法调用都解释为相应的 Permission 对象，并将它作为输入参数传递给 AccessController 类的 checkPermission() 方法。</xxx></p>
<h3 id="权限的继承和优化问题"><a href="#权限的继承和优化问题" class="headerlink" title="权限的继承和优化问题"></a>权限的继承和优化问题</h3><blockquote>
<p>如果说类A调用了类B,B调用了类C,那么C的权限就是ABC权限的交集</p>
</blockquote>
<h3 id="最终节-gt-看java的AccessController-doPrivileged"><a href="#最终节-gt-看java的AccessController-doPrivileged" class="headerlink" title="最终节-&gt; 看java的AccessController.doPrivileged"></a>最终节-&gt; 看java的AccessController.doPrivileged</h3><ul>
<li>通过上面的引子,终于了解的这个方法是干啥的了,这个方法就是解决这样一个问题,<strong>如果A调用了B,但是A的权限太小,B的权限太大导致,A影响了B的功能,这个使用使用上面的方法,这个方法将会让jvm进行权限计算的时候将会使用B最为最顶层的权限,这个样A或者A之前的权限就对B和B之后的不起作用了</strong></li>
</ul>
<h3 id="一个简单的小例子"><a href="#一个简单的小例子" class="headerlink" title="一个简单的小例子"></a>一个简单的小例子</h3><h4 id="策略文件-JREHOME-lib-security-java-policy"><a href="#策略文件-JREHOME-lib-security-java-policy" class="headerlink" title="策略文件$JREHOME/lib/security/java.policy"></a>策略文件$JREHOME/lib/security/java.policy</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Standard extensions get all permissions by default</span></span><br><span class="line"></span><br><span class="line">grant codeBase <span class="string">"file:$&#123;&#123;java.ext.dirs&#125;&#125;/*"</span> &#123;</span><br><span class="line">        permission java.security.AllPermission;</span><br></pre></td></tr></table></figure>
<h4 id="参数文件-JREHOME-lib-security-java-security-用来指定运行安全模式下的各种参数-比如在哪里加载策略文件"><a href="#参数文件-JREHOME-lib-security-java-security-用来指定运行安全模式下的各种参数-比如在哪里加载策略文件" class="headerlink" title="参数文件$JREHOME/lib/security/java.security-用来指定运行安全模式下的各种参数(比如在哪里加载策略文件)\"></a>参数文件$JREHOME/lib/security/java.security-用来指定运行安全模式下的各种参数(比如在哪里加载策略文件)\</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"># The default is to have a single system-wide policy file,</span><br><span class="line"># and a policy file in the user's home directory.</span><br><span class="line">policy.url.1=file:$&#123;java.home&#125;/lib/security/java.policy</span><br><span class="line">policy.url.2=file:$&#123;user.home&#125;/.java.policy</span><br><span class="line"># whether or not we expand properties in the policy file</span><br><span class="line"># if this is set to false, properties ($&#123;...&#125;) will not be expanded in policy</span><br><span class="line"># files.</span><br><span class="line">policy.expandProperties=<span class="keyword">true</span></span><br><span class="line"># whether or not we allow an extra policy to be passed on the command line</span><br><span class="line"># with -Djava.security.policy=somefile. Comment out this line to disable</span><br><span class="line"># this feature.</span><br><span class="line">policy.allowSystemProperty=<span class="keyword">true</span></span><br></pre></td></tr></table></figure>
<h4 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.io.File;</span><br><span class="line"><span class="keyword">import</span> java.io.FileInputStream;</span><br><span class="line"><span class="keyword">import</span> java.io.FileNotFoundException;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.io.InputStream;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PolicyTest</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">file</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        File f = <span class="keyword">new</span> File(<span class="string">"r.txt"</span>);</span><br><span class="line">        InputStream is;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            is = <span class="keyword">new</span> FileInputStream(f);</span><br><span class="line">            <span class="keyword">byte</span>[] content = <span class="keyword">new</span> <span class="keyword">byte</span>[<span class="number">1024</span>];</span><br><span class="line">            <span class="keyword">while</span> (is.read(content) != -<span class="number">1</span>) &#123;</span><br><span class="line">                System.out.println(<span class="keyword">new</span> String(content));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (FileNotFoundException e) &#123;</span><br><span class="line">            <span class="comment">// TODO Auto-generated catch block</span></span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            <span class="comment">// TODO Auto-generated catch block</span></span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        <span class="comment">// test read file.</span></span><br><span class="line">        file();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>启动参数加入-Djava.security.manager使用安全沙箱模式运行,将会报错</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Exception in thread <span class="string">"main"</span> java.security.AccessControlException: <span class="function">access <span class="title">denied</span><span class="params">(<span class="string">"java.io.FilePermission"</span> <span class="string">"D:githubCDLibsrcmainresourcessecurityr.txt"</span> <span class="string">"read"</span>)</span></span></span><br><span class="line"><span class="function">at java.security.AccessControlContext.<span class="title">checkPermission</span><span class="params">(Unknown Source)</span></span></span><br><span class="line"><span class="function">at java.security.AccessController.<span class="title">checkPermission</span><span class="params">(Unknown Source)</span></span></span><br><span class="line"><span class="function">at java.lang.SecurityManager.<span class="title">checkPermission</span><span class="params">(Unknown Source)</span></span></span><br><span class="line"><span class="function">at java.lang.SecurityManager.<span class="title">checkRead</span><span class="params">(Unknown Source)</span></span></span><br><span class="line"><span class="function">at java.io.FileInputStream.&lt;init&gt;<span class="params">(Unknown Source)</span></span></span><br><span class="line"><span class="function">at com.taobao.cd.security.PolicyTest.<span class="title">main</span><span class="params">(PolicyTest.java:<span class="number">15</span>)</span></span></span><br></pre></td></tr></table></figure>
<p>这样,在权限文件中添加一条这样的规则</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">grant &#123;</span><br><span class="line">    permission java.io.FilePermission <span class="string">"D:\\github\\CDLib\\src\\main\\resources\\security\\*"</span>, <span class="string">"read"</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>然后代码就通过了</p>
<h3 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h3><blockquote>
<p>这个特性感觉使用的应该不多,框架里用的挺多,比较冷门记录一下</p>
</blockquote>

          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/spring5(三)-生命周期,容器扩展,lookup模式,事件/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/spring5(三)-生命周期,容器扩展,lookup模式,事件/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h3 id="spring-javabean的生命周期-容器扩展-lookup方法-spring事件"><a href="#spring-javabean的生命周期-容器扩展-lookup方法-spring事件" class="headerlink" title="spring javabean的生命周期\容器扩展\lookup方法\spring事件"></a>spring javabean的生命周期\容器扩展\lookup方法\spring事件</h3><h4 id="javabean-生命周期控制"><a href="#javabean-生命周期控制" class="headerlink" title="javabean 生命周期控制"></a>javabean 生命周期控制</h4><p><img src="blogimg/spring/1.jpeg" alt=""></p>
<ul>
<li>使用配置文件的方法</li>
</ul>
<blockquote>
<p>注意 <beans>标签中可以配置全局使用的初始化方法和销毁方法</beans></p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">	<span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">	<span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"</span></span></span><br><span class="line"><span class="tag">	<span class="attr">default-init-method</span>=<span class="string">""</span> <span class="attr">default-destroy-method</span>=<span class="string">""</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"mybean"</span> <span class="attr">class</span>=<span class="string">"h_Bean的生命周期.MyBean"</span> <span class="attr">init-method</span>=<span class="string">"init"</span></span></span><br><span class="line"><span class="tag">		<span class="attr">destroy-method</span>=<span class="string">"Mydestroy"</span>&gt;</span>  <span class="comment">&lt;!-- 使用init-method 的 destroy—method 方法指定生命周期的指定和完成方法 --&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>
<ul>
<li>使用注解和接口相关的配置方法</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.DisposableBean;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.InitializingBean;</span><br><span class="line"><span class="comment">//使用bean的生命周期配置 - 注意bean的生命周期只是针对单例模式下的bean对象因为对于非单例模式 spring框架只进行创建而不管其他的用途</span></span><br><span class="line"><span class="comment">//所以spring框架对非单利模式不进行生命周期的检测</span></span><br><span class="line"><span class="comment">//InitializingBean接口表示bean对象在全部的依赖关系都被设置之后将会被自动的进行调用</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyBean</span> <span class="keyword">implements</span> <span class="title">InitializingBean</span>,<span class="title">DisposableBean</span></span>&#123;</span><br><span class="line">	<span class="comment">//接口中定义的初始化方法</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterPropertiesSet</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;&#125;</span><br><span class="line">	<span class="comment">//接口中定义的销毁方法</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">destroy</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>&#123;&#125;</span><br><span class="line">	<span class="comment">//配置文件中定义的初始化方法</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">init</span><span class="params">()</span></span>&#123;&#125;</span><br><span class="line">	<span class="comment">//配置文件中定义的销毁方法</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">Mydestroy</span><span class="params">()</span></span>&#123;&#125;</span><br><span class="line">	<span class="comment">//这些方法的调用顺序是先调用接口的方法再掉用配置文件中的方法</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<blockquote>
<p>注意：接口的执行优先级无论是初始化或者销毁都比配置文件放有限执行, SmartInitializingSingleton 所有非lazy单例Bean实例化完成后的回调方法</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MySmartInitializingSingleton</span> <span class="keyword">implements</span> <span class="title">SmartInitializingSingleton</span> </span>&#123;</span><br><span class="line">    <span class="comment">//所有非lazy单例Bean实例化完成后，会调用该方法</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterSingletonsInstantiated</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"单例Bean实例化完成了"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>spring 中bean的生命周期的配置除了使用 xml 指定 的方法之外还能使用注解的方法进行相关的配置</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostConstruct</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">methodinit</span><span class="params">()</span></span>&#123;&#125;</span><br><span class="line"><span class="meta">@PreDestroy</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">methoddestry</span><span class="params">()</span></span>&#123;&#125;;</span><br></pre></td></tr></table></figure>
<p>同时spring还提供了让bean和容器进行相关关联bean 方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Lifecycle</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">start</span><span class="params">()</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">stop</span><span class="params">()</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">boolean</span> <span class="title">isRunning</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">LifecycleProcessor</span> <span class="keyword">extends</span> <span class="title">Lifecycle</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">onRefresh</span><span class="params">()</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">onClose</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">Phased</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">int</span> <span class="title">getPhase</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">SmartLifecycle</span> <span class="keyword">extends</span> <span class="title">Lifecycle</span>, <span class="title">Phased</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">boolean</span> <span class="title">isAutoStartup</span><span class="params">()</span></span>;</span><br><span class="line">  <span class="function"><span class="keyword">void</span> <span class="title">stop</span><span class="params">(Runnable callback)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>所有的bean都可以实现这些接口，然后在容器进行增加或者删除的时候将会自动的执行相关的方法，注意SmartLifecycle 接口中的stop方法将会传入一个实现runnabe接口的类，容器在进行销毁之后将会自动的异步执行这个类中的相关的run方法，Phased的getphase将会设置一个等级，用来表示优先级</p>
<p><strong>引申 ：spring容器可以使用ctx.registerShutdownHook(); 方法实现优雅停机操作</strong></p>
<h4 id="spring-后置处理器-容器扩展方法"><a href="#spring-后置处理器-容器扩展方法" class="headerlink" title="spring 后置处理器 (容器扩展方法)"></a>spring 后置处理器 (容器扩展方法)</h4><ol>
<li>BeanPostProcessors接口</li>
</ol>
<p>如果这个接口的某个实现类被注册到某个容器，那么该容器的每个受管Bean在调用初始化方法之前，都会获得该接口实现类的一个回调。容器调用接口定义的方法时会将该受管<strong>Bean的实例和名字通过参数传入方法</strong>，进过处理后通过方法的返回值返回给容器。</p>
<p>要使用BeanPostProcessor回调，就必须先在容器中注册实现该接口的类，BeanFactory和ApplicationContext容器的注册方式不大一样：</p>
<ul>
<li>若使用BeanFactory，则必须要显示的调用其addBeanPostProcessor()方法进行注册，参数为BeanPostProcessor实现类的实例.</li>
<li>如果是使用ApplicationContext，那么容器会在配置文件在中自动寻找实现了BeanPostProcessor接口的Bean，然后自动注册，我们要做的只是配置一个BeanPostProcessor实现类的Bean就可以了。</li>
</ul>
<p>假如我们使用了多个的BeanPostProcessor的实现类，只要实现Ordered接口，设置order属性就可以确定不同实现类的处理顺序了。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.beans.BeansException;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.config.BeanPostProcessor;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JavaBeanPostProcessor</span> <span class="keyword">implements</span> <span class="title">BeanPostProcessor</span></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">postProcessBeforeInitialization</span><span class="params">(Object bean, String beanName)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"BeanPostProcessor:before"</span>+beanName);</span><br><span class="line">        <span class="keyword">return</span> bean;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">postProcessAfterInitialization</span><span class="params">(Object bean, String beanName)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"BeanPostProcessor:after"</span>+beanName);</span><br><span class="line">        <span class="keyword">return</span> bean;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>注意其中的after和before的方法,这两个方法将会在声明周期的初始化之前和初始化之后进行调用,传入的bean 就是 需要使用的Bean 传入的beanName就是配置的beanname , 一般就是对指定的相关的bean进行处理</p>
<ol start="2">
<li>BeanFactoryPostProcessor接口</li>
</ol>
<p>BeanFactoryPostProcessor接口实现类可以在当前BeanFactory初始化后，bean实例化之前对BeanFactory做一些处理。BeanFactoryPostProcessor是针对于bean容器的，在调用它时，BeanFactory只加载了bean的定义，还没有对它们进行实例化，所以我们可以通过对BeanFactory的处理来达到影响之后实例化bean的效果。跟BeanPostProcessor一样，ApplicationContext也能自动检测和调用容器中的BeanFactoryPostProcessor。<br>接口的信息如下:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.meituan.hyt.test1;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.BeansException;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.config.BeanFactoryPostProcessor;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.config.ConfigurableListableBeanFactory;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserBeanFactoryPostProcessor</span> <span class="keyword">implements</span> <span class="title">BeanFactoryPostProcessor</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">postProcessBeanFactory</span><span class="params">(ConfigurableListableBeanFactory configurableListableBeanFactory)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"BeanFactoryPostProcessor doing"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>在spring中有一些特殊的操作就是使用BeanFactoryPostProcessor接口，比如类名替换PropertyPlaceholderConfigurer。他可以自动将相关的java properties信息替换成需要的,这里分析一下这个类:</p>
<p><img src="blogimg/spring/2.jpg" alt=""></p>
<p>接口:InitializingBean  — 只有一个方法afterPropertiesSet 当bean实例化之后将会调用这个方法,我们可以在这里初始化一下属性<br>接口:order 可以指定优先级<br>接口:BeanNameAware和BeanFactory 配置配置回调将容器的和配置的相关参数传入<br>类: PropertiesLoaderSupport,PropertyResourceConfigurer  将配置文件中的参数进行绑定,提供配置文件解析功能<br>类:PlaceholderConfigurerSupport 真正的实现插入方法,这个类最核心的方法:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//遍历给定的BeanDefinition对象和它们中包含的MutablePropertyValues和ConstructorArgumentValues。</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">visitBeanDefinition</span><span class="params">(BeanDefinition beanDefinition)</span> </span>&#123;</span><br><span class="line">	visitParentName(beanDefinition);</span><br><span class="line">	visitBeanClassName(beanDefinition);</span><br><span class="line">	visitFactoryBeanName(beanDefinition);</span><br><span class="line">	visitFactoryMethodName(beanDefinition);</span><br><span class="line">	visitScope(beanDefinition);</span><br><span class="line">	<span class="keyword">if</span> (beanDefinition.hasPropertyValues()) &#123;</span><br><span class="line">		visitPropertyValues(beanDefinition.getPropertyValues());</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">if</span> (beanDefinition.hasConstructorArgumentValues()) &#123;</span><br><span class="line">		ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();</span><br><span class="line">		visitIndexedArgumentValues(cas.getIndexedArgumentValues());</span><br><span class="line">		visitGenericArgumentValues(cas.getGenericArgumentValues());</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>遍历给定的BeanDefinition对象和它们中包含的MutablePropertyValues和ConstructorArgumentValues。</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;bean <span class="class"><span class="keyword">class</span></span>=<span class="string">"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"</span>&gt;</span><br><span class="line">    &lt;property name=<span class="string">"locations"</span> value=<span class="string">"classpath:com/foo/jdbc.properties"</span>/&gt;</span><br><span class="line">&lt;/bean&gt;</span><br><span class="line">&lt;bean id=<span class="string">"dataSource"</span> destroy-method=<span class="string">"close"</span></span><br><span class="line">        <span class="class"><span class="keyword">class</span></span>=<span class="string">"org.apache.commons.dbcp.BasicDataSource"</span>&gt;</span><br><span class="line">    &lt;property name=<span class="string">"driverClassName"</span> value=<span class="string">"$&#123;jdbc.driverClassName&#125;"</span>/&gt;</span><br><span class="line">    &lt;property name=<span class="string">"url"</span> value=<span class="string">"$&#123;jdbc.url&#125;"</span>/&gt;</span><br><span class="line">    &lt;property name=<span class="string">"username"</span> value=<span class="string">"$&#123;jdbc.username&#125;"</span>/&gt;</span><br><span class="line">    &lt;property name=<span class="string">"password"</span> value=<span class="string">"$&#123;jdbc.password&#125;"</span>/&gt;</span><br><span class="line">&lt;/bean&gt;</span><br></pre></td></tr></table></figure>
<p>注意其中有BeanFactoryPostProcessor的使用方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyBeanFactoryPostProcessor</span> <span class="keyword">implements</span> <span class="title">BeanFactoryPostProcessor</span> </span>&#123;</span><br><span class="line">   <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">postProcessBeanFactory</span><span class="params">(ConfigurableListableBeanFactory beanFactory)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">      System.out.println(<span class="string">"调用MyBeanFactoryPostProcessor的postProcessBeanFactory"</span>);</span><br><span class="line">      BeanDefinition bd = beanFactory.getBeanDefinition(<span class="string">"myJavaBean"</span>);</span><br><span class="line">      MutablePropertyValues pv =  bd.getPropertyValues();</span><br><span class="line">      <span class="keyword">if</span> (pv.contains(<span class="string">"remark"</span>)) &#123;</span><br><span class="line">          pv.addPropertyValue(<span class="string">"remark"</span>, <span class="string">"在BeanFactoryPostProcessor中修改之后的备忘信息"</span>);</span><br><span class="line">      &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>其中的postProcessBeanFactory这个方法中的参数是决定BeanFactoryPostProcessor强于BeanPostProcessor的关键之处,其中有一个参数:<strong>ConfigurableListableBeanFactory</strong>,这个参数可以进行配置相关的配置首先具体见下</p>
<p>这个接口只有一个实现类:DefaultListableBeanFactory</p>
<p>看一下关系继承图</p>
<p><img src="blogimg/spring/3.jpg" alt=""></p>
<p>重点关注这个接口:ConfigurableListableBeanFactory,这个接口继承了ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory 这三个接口 </p>
<ol start="0">
<li>BeanFactory 主要提供getbean ,和isSingleType 这样的方法</li>
<li>ListableBeanFactory 这个接口是BeanFactory接口的实现之一(还有HierarchicalBeanFactory,AutowireCapableBeanFactory),这个主要是获取容器中各种相关javabean属性的方法,比如有 getBeansOfType,getBeansWithAnnotation 这种方法,</li>
<li>AutowireCapableBeanFactory 提供自动装配扩展(用来分层将功能细化)</li>
<li>HierarchicalBeanFactory 其中有一个方法,getParentBeanFactory 这里提供分级功能,实现了这个接口可以获取夫工厂方法</li>
<li>ConfigurableListableBeanFactory 这个接口同时继承了ListableBeanFactory,AutowireCapableBeanFactory,HierarchicalBeanFactory.</li>
</ol>
<p>如果看一些上面这些类就会有一个大致上的理解了</p>
<p>spring 通过各种继承和接口扩展了这个类的使用方法,将相关的各种功能尽心组装(一个接口专注一个点记性细化,上层实现,典型的oop思想)</p>
<p>ConfigurableListableBeanFactory 接口继承了上面的这些接口,所以他拥有获取所有的相关的javaBean集合的能力,并且拥有在初始化之前对属性进行操作的能力.</p>
<h4 id="单例模式下实现内部变量非单例配置"><a href="#单例模式下实现内部变量非单例配置" class="headerlink" title="单例模式下实现内部变量非单例配置"></a>单例模式下实现内部变量非单例配置</h4><blockquote>
<p>之前在博客中做过测试，在spring容器中单例模式注入非单例模式属性的时候其实各个元素注入的是相同的类（使用工厂方法进行注入的时候也是如此）（==返回true），想要获取不同的属性就要使用lookup标签</p>
</blockquote>
<p><strong>配置文件</strong></p>
<blockquote>
<p>spring框架在抽象类中将会自动使用动态代理实现这个抽象方法，讲指定的bean对象进行返回如果对象实现了借口  spring框架将会使用jdk代理 否则使用cglib代理  推荐使用接口</p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">	<span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">	<span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"beanone"</span> <span class="attr">class</span>=<span class="string">"BeanOne"</span> <span class="attr">scope</span>=<span class="string">"prototype"</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"name"</span> <span class="attr">value</span>=<span class="string">"beanone2"</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"age"</span> <span class="attr">value</span>=<span class="string">"1234"</span>&gt;</span><span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"lookupclass"</span> <span class="attr">class</span>=<span class="string">"LookupClass"</span>&gt;</span></span><br><span class="line">		<span class="tag">&lt;<span class="name">lookup-method</span> <span class="attr">name</span>=<span class="string">"getBeanOne"</span> <span class="attr">bean</span>=<span class="string">"beanone"</span>&gt;</span><span class="tag">&lt;/<span class="name">lookup-method</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p><strong>Lookup类</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">LookupClass</span> </span>&#123;</span><br><span class="line">	<span class="function"><span class="keyword">abstract</span> <span class="keyword">public</span> BeanOne <span class="title">getBeanOne</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="javabean"><a href="#javabean" class="headerlink" title="javabean"></a>javabean</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BeanOne</span> </span>&#123;</span><br><span class="line">	<span class="keyword">private</span> String name;</span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">int</span> age;</span><br><span class="line">	<span class="keyword">private</span> BeanTwo beanTwo;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> name;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.name = name;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getAge</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> age;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAge</span><span class="params">(<span class="keyword">int</span> age)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.age = age;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> BeanTwo <span class="title">getBeanTwo</span><span class="params">()</span> </span>&#123;</span><br><span class="line">		<span class="keyword">return</span> beanTwo;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setBeanTwo</span><span class="params">(BeanTwo beanTwo)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">this</span>.beanTwo = beanTwo;</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="spring-message机制"><a href="#spring-message机制" class="headerlink" title="spring  message机制"></a>spring  message机制</h4><p>该ApplicationContext接口扩展了一个称为的接口MessageSource，因此提供了国际化（i18n）功能。Spring还提供了HierarchicalMessageSource可以分层解析消息的接口。这些接口一起为Spring特效消息解析提供了基础。这些接口上定义的方法包括：</p>
<ul>
<li><p>String getMessage(String code, Object[] args, String default, Locale loc)：用于从中检索消息的基本方法MessageSource。如果未找到指定语言环境的消息，则使用默认消息。使用MessageFormat标准库提供的功能，传入的任何参数都将成为替换值。</p>
</li>
<li><p>String getMessage(String code, Object[] args, Locale loc)：与前面的方法基本相同，但有一点不同：不能指定默认消息; 如果无法找到消息，NoSuchMessageException则会抛出a。</p>
</li>
<li><p>String getMessage(MessageSourceResolvable resolvable, Locale locale)：前面方法中使用的所有属性也都包含在一个名为的类中 MessageSourceResolvable，您可以使用该方法。</p>
</li>
</ul>
<blockquote>
<p>注意:当一个ApplicationContext被加载时，它会自动搜索上下文中实现MessageSource 接口的bean。这个bean的名字必须是messageSource,如果 ApplicationContext无法找到任何消息源，DelegatingMessageSource则会实例化一个空 以便能够接受对上面定义的方法的调用。</p>
</blockquote>
<p>Spring提供了两个MessageSource实现，ResourceBundleMessageSource并且 StaticMessageSource。两者都是HierarchicalMessageSource为了做嵌套消息传递而实现的。这StaticMessageSource是很少使用，但提供了编程方式来添加消息到源。在ResourceBundleMessageSource被示出在下面的例子：</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">beans</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"messageSource"</span></span></span><br><span class="line"><span class="tag">            <span class="attr">class</span>=<span class="string">"org.springframework.context.support.ResourceBundleMessageSource"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"basenames"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">list</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">value</span>&gt;</span>format<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">value</span>&gt;</span>exceptions<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">value</span>&gt;</span>windows<span class="tag">&lt;/<span class="name">value</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">list</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">property</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>例子中 <value> 标签中的数据表示的是数据名称 对应的文件是 format.properties文件,举例子为format.properties中的信息</value></p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># in format.properties</span><br><span class="line">message=Ebagum lad, the &#123;0&#125; argument is required, I say, required.</span><br></pre></td></tr></table></figure>
<p>使用这个方法<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">    MessageSource resources = <span class="keyword">new</span> ClassPathXmlApplicationContext(<span class="string">"beans.xml"</span>);</span><br><span class="line">    String message = resources.getMessage(<span class="string">"message"</span>,</span><br><span class="line">        <span class="keyword">new</span> Object [] &#123;<span class="string">"userDao"</span>&#125;, <span class="string">"Required"</span>, Locale.UK);</span><br><span class="line">    System.out.println(message);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>输出为</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Ebagum lad, the &apos;userDao&apos; argument is required, I say, required.</span><br></pre></td></tr></table></figure>
<h4 id="spring事件-Event"><a href="#spring事件-Event" class="headerlink" title="spring事件 Event"></a>spring事件 Event</h4><blockquote>
<p>其实就是实现一个event 和 一个listener的过程</p>
</blockquote>
<p><strong>event 一个事件</strong></p>
<blockquote>
<p>定义一个event事件:并不需要在配置文件中进行配置，是需要使用application手动发出   实现 ApplicationEvent接口</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationEvent;</span><br><span class="line"><span class="comment">//实现spring相应首先要进行spring event事件的注册</span></span><br><span class="line"><span class="comment">//这个方法只是一个封装器-用来将事件进行封装通过接口传递到 实现类中 然后在发出事件</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyApplicationEvent</span> <span class="keyword">extends</span> <span class="title">ApplicationEvent</span></span>&#123;</span><br><span class="line">	<span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> serialVersionUID = <span class="number">1L</span>;</span><br><span class="line">	Object object =<span class="keyword">null</span>;</span><br><span class="line">	<span class="comment">//注意这里的第一个参数其实没有什么用就是为了个事件一个参数进行生成一个标号 传递过来的source将会在使用后变成空值</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="title">MyApplicationEvent</span><span class="params">(Object source,String string)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">super</span>(source);</span><br><span class="line">		<span class="comment">// TODO Auto-generated constructor stub</span></span><br><span class="line">		<span class="keyword">this</span>.object=string;</span><br><span class="line">		System.out.println(object.toString());</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">say</span><span class="params">()</span></span>&#123;</span><br><span class="line">		<span class="keyword">if</span>(<span class="keyword">this</span>.object!=<span class="keyword">null</span>)&#123;</span><br><span class="line">			System.out.println(object.toString());</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">else</span>&#123;</span><br><span class="line">			System.out.println(<span class="string">"this object is Null!!"</span>);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>spring 发布一个一个event事件</strong></p>
<p>在spring中任何一个可以发布事件的方法都实现了一个ApplicationEventPublisher接口,applicationContext就是其中的一个实现类</p>
<p>我们在自己进行开发的时候并不需要实现这个接口只要实现一个ApplicationEventPublisherAware , spring 容器就回自动的将相关的属性注入到这个这个bean中</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">EmailService</span> <span class="keyword">implements</span> <span class="title">ApplicationEventPublisherAware</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> List&lt;String&gt; blackList;</span><br><span class="line">    <span class="keyword">private</span> ApplicationEventPublisher publisher;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setBlackList</span><span class="params">(List&lt;String&gt; blackList)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.blackList = blackList;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setApplicationEventPublisher</span><span class="params">(ApplicationEventPublisher publisher)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.publisher = publisher;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">sendEmail</span><span class="params">(String address, String text)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (blackList.contains(address)) &#123;</span><br><span class="line">            BlackListEvent event = <span class="keyword">new</span> BlackListEvent(<span class="keyword">this</span>, address, text);</span><br><span class="line">            publisher.publishEvent(event);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>spring监听event</strong></p>
<p>ApplicationListener   这个监听器需要在bean中进行配置，spring容器会自动的处理event</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationEvent;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationListener;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.event.ContextClosedEvent;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.event.ContextRefreshedEvent;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.event.ContextStartedEvent;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.event.ContextStoppedEvent;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">import</span> c_spring_applicationContext的事件机制.applicationEvent.MyApplicationEvent;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyApplicationListener</span> <span class="keyword">implements</span> <span class="title">ApplicationListener</span>&lt;<span class="title">ApplicationEvent</span>&gt;</span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onApplicationEvent</span><span class="params">(ApplicationEvent arg0)</span> </span>&#123;</span><br><span class="line">		<span class="keyword">if</span> (arg0 <span class="keyword">instanceof</span> MyApplicationEvent)&#123;</span><br><span class="line">			((MyApplicationEvent) arg0).say();</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//指的是xml文件加载完成并且可用后发出的事件</span></span><br><span class="line">		<span class="keyword">if</span> (arg0 <span class="keyword">instanceof</span> ContextRefreshedEvent)&#123;</span><br><span class="line">			((MyApplicationEvent) arg0).say();</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//当ConfigurableApplicationContext 接口的start（）方法的时候触发这个方法 </span></span><br><span class="line">		<span class="keyword">if</span> (arg0 <span class="keyword">instanceof</span> ContextStartedEvent)&#123;</span><br><span class="line">			((MyApplicationEvent) arg0).say();</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//当ConfigurableApplicationContext 接口的close（）方法的时候触发这个方法 </span></span><br><span class="line">		<span class="keyword">if</span> (arg0 <span class="keyword">instanceof</span> ContextClosedEvent)&#123;</span><br><span class="line">			((MyApplicationEvent) arg0).say();</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//当ConfigurableApplicationContext 接口的stop（）方法的时候触发这个方法 </span></span><br><span class="line">		<span class="keyword">if</span> (arg0 <span class="keyword">instanceof</span> ContextStoppedEvent)&#123;</span><br><span class="line">			((MyApplicationEvent) arg0).say();</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="comment">//requestHandledEvent web相关的事件 只能使用 dispatcherServlet的web应用当中 当用户请求结束的时候将会自动触发</span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>xml配置文件</strong></p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">	<span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">	<span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"myapplicationListener"</span> <span class="attr">class</span>=<span class="string">"c_spring_applicationContext的事件机制.applicationEventListener.MyApplicationListener"</span>&gt;</span></span><br><span class="line">		<span class="comment">&lt;!-- 当时用监听方法的时候必须必须将监听listener注册到bean容器内这样spring框架才能自动进行调用 --&gt;</span></span><br><span class="line">		<span class="comment">&lt;!-- event事件spring设计的时候就没有将他设计为能加入进bean容器的方法因为没有空的构造函数 --&gt;</span></span><br><span class="line">	<span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line">	<span class="comment">&lt;!-- 注册了监听器将会自动的进行监听相关的各种event --&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h4 id="spring-bean获得容器和自身相关属性"><a href="#spring-bean获得容器和自身相关属性" class="headerlink" title="spring bean获得容器和自身相关属性"></a>spring bean获得容器和自身相关属性</h4><p>spring 中bean获得spring 需要实现一下两个接口</p>
<ul>
<li>ApplicationContextAware</li>
<li>BeanFactoryAware</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.beans.BeansException;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.BeanFactory;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.BeanFactoryAware;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationContext;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.ApplicationContextAware;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestBean</span> <span class="keyword">implements</span> <span class="title">ApplicationContextAware</span>,<span class="title">BeanFactoryAware</span></span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setBeanFactory</span><span class="params">(BeanFactory beanFactory)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">		<span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line">		<span class="comment">//传入的参数就是需要进行使用的容器</span></span><br><span class="line">	&#125;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setApplicationContext</span><span class="params">(ApplicationContext applicationContext)</span> <span class="keyword">throws</span> BeansException </span>&#123;</span><br><span class="line">		<span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line">		<span class="comment">//传入的参数就是需要进行使用的容器</span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>spring bean获得自身的相关配置属性使用如下的接口</p>
<ul>
<li>BeanClassLoaderAware</li>
<li>BeanNameAware</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.BeanClassLoaderAware;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.BeanNameAware;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestBean</span> <span class="keyword">implements</span> <span class="title">BeanNameAware</span>,<span class="title">BeanClassLoaderAware</span></span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setBeanClassLoader</span><span class="params">(ClassLoader classLoader)</span> </span>&#123;</span><br><span class="line">		<span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line">		</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setBeanName</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">		<span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line">		</span><br><span class="line">	&#125;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
      

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/java-关于system.gc()与finalize()方法/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
                
                <a class="post-title-link" href="/2018/10/09/java-关于system.gc()与finalize()方法/" itemprop="url">未命名</a></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        
          
            <h3 id="1-finalize的作用"><a href="#1-finalize的作用" class="headerlink" title="1. finalize的作用"></a>1. finalize的作用</h3><ul>
<li><p>finalize()是Object的protected方法，子类可以覆盖该方法以实现资源清理工作，GC在回收对象之前调用该方法。</p>
</li>
<li><p>finalize()与C++中的析构函数不是对应的。C++中的析构函数调用的时机是确定的（对象离开作用域或delete掉），但Java中的finalize的调用具有不确定性</p>
</li>
<li><p>不建议用finalize方法完成“非内存资源”的清理工作，但建议用于：① 清理本地对象(通过JNI创建的对象)；② 作为确保某些非内存资源(如Socket、文件等)释放的一个补充：在finalize方法中显式调用其他资源释放方法。其原因可见下文[finalize的问题]</p>
<h3 id="2-finalize的问题"><a href="#2-finalize的问题" class="headerlink" title="2. finalize的问题"></a>2. finalize的问题</h3></li>
</ul>
<ol>
<li><p>一些与finalize相关的方法，由于一些致命的缺陷，已经被废弃了，如System.runFinalizersOnExit()方法、Runtime.runFinalizersOnExit()方法<br>System.gc()与System.runFinalization()方法增加了finalize方法执行的机会，但不可盲目依赖它们</p>
</li>
<li><p>Java语言规范并不保证finalize方法会被及时地执行、而且根本不会保证它们会被执行<br>finalize方法可能会带来性能问题。因为JVM通常在单独的低优先级线程中完成finalize的执行<br>对象再生问题：finalize方法中，可将待回收对象赋值给GC Roots可达的对象引用，从而达到对象再生的目的</p>
</li>
<li><p>finalize方法至多由GC执行一次且只执行一次(用户当然可以手动调用对象的finalize方法，但并不影响GC对finalize的行为)</p>
<h3 id="3-finalize的执行过程-生命周期"><a href="#3-finalize的执行过程-生命周期" class="headerlink" title="3. finalize的执行过程(生命周期)"></a>3. finalize的执行过程(生命周期)</h3></li>
</ol>
<p>描述一下finalize流程：</p>
<ol>
<li><p>当对象变成(GC Roots)不可达时，GC会判断该对象是否覆盖了finalize方法，若未覆盖，则直接将其回收。否则，若对象未执行过finalize方法，将其放入F-Queue队列，由一低优先级线程执行该队列中对象的finalize方法。</p>
</li>
<li><p>执行finalize方法完毕后，GC会再次判断该对象是否可达，若不可达，则进行回收，否则，对象“复活”。</p>
</li>
</ol>
<p>具体的finalize流程： </p>
<p>对象可由<strong>两种状态控制</strong>，涉及到两类状态空间，一是终结状态空间 F = {unfinalized, finalizable, finalized}；二是可达状态空间 R = {reachable, finalizer-reachable, unreachable}。</p>
<p>各状态含义如下： </p>
<ul>
<li>unfinalized: 新建对象会先进入此状态，GC并未准备执行其finalize方法，因为该对象是可达的</li>
<li>finalizable: 表示GC可对该对象执行finalize方法，GC已检测到该对象不可达。正如前面所述，GC通过F-Queue队列和一专用线程完成finalize的执行</li>
<li>finalized: 表示GC已经对该对象执行过finalize方法</li>
<li>reachable: 表示GC Roots引用可达</li>
<li><p>finalizer-reachable(f-reachable)：表示不是reachable，但可通过某个finalizable对象可达</p>
</li>
<li><p>unreachable：对象不可通过上面两种途径可达</p>
</li>
</ul>
<blockquote>
<p>状态变迁图：</p>
</blockquote>
<p><img src="blogimg/java/10.png" alt=""></p>
<blockquote>
<p>变迁说明： </p>
</blockquote>
<ol>
<li>新建对象首先处于[reachable, unfinalized]状态(A) </li>
<li>随着程序的运行，一些引用关系会消失，导致状态变迁，从reachable状态变迁到f-reachable(B, C, D)或unreachable(E, F)状态 </li>
<li>若JVM检测到处于unfinalized状态的对象变成f-reachable或unreachable，JVM会将其标记为finalizable状态(G,H)。若对象原处于[unreachable, unfinalized]状态，则同时将其标记为f-reachable(H)。 </li>
<li>在某个时刻，JVM取出某个finalizable对象，将其标记为finalized并在某个线程中执行其finalize方法。由于是在活动线程中引用了该对象，该对象将变迁到(reachable, finalized)状态(K或J)。该动作将影响某些其他对象从f-reachable状态重新回到reachable状态(L, M, N) </li>
<li>处于finalizable状态的对象不能同时是unreachable的，由第4点可知，将对象finalizable对象标记为finalized时会由某个线程执行该对象的finalize方法，致使其变成reachable。这也是图中只有八个状态点的原因 </li>
<li>程序员手动调用finalize方法并不会影响到上述内部标记的变化，因此JVM只会至多调用finalize一次，即使该对象“复活”也是如此。程序员手动调用多少次不影响JVM的行为 </li>
<li>若JVM检测到finalized状态的对象变成unreachable，回收其内存(I) </li>
<li>若对象并未覆盖finalize方法，JVM会进行优化，直接回收对象（O） </li>
<li>注：System.runFinalizersOnExit()等方法可以使对象即使处于reachable状态，JVM仍对其执行finalize方法</li>
</ol>
<blockquote>
<p>意思的示例代码</p>
</blockquote>
<ol>
<li>对象复活</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.kys;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GC</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> GC SAVE_HOOK = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> InterruptedException </span>&#123;</span><br><span class="line">        SAVE_HOOK = <span class="keyword">new</span> GC();</span><br><span class="line">        SAVE_HOOK = <span class="keyword">null</span>;</span><br><span class="line">        System.gc();</span><br><span class="line">        Thread.sleep(<span class="number">500</span>);</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">null</span> != SAVE_HOOK) &#123; <span class="comment">//此时对象应该处于(reachable, finalized)状态</span></span><br><span class="line">            System.out.println(<span class="string">"Yes , I am still alive"</span>+<span class="string">":"</span>+SAVE_HOOK);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">"No , I am dead"</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        SAVE_HOOK = <span class="keyword">null</span>;</span><br><span class="line">        System.gc();</span><br><span class="line">        Thread.sleep(<span class="number">500</span>);</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">null</span> != SAVE_HOOK) &#123;</span><br><span class="line">            System.out.println(<span class="string">"Yes , I am still alive"</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">"No , I am dead"</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">finalize</span><span class="params">()</span> <span class="keyword">throws</span> Throwable </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.finalize();</span><br><span class="line">        System.out.println(<span class="string">"execute method finalize()"</span>);</span><br><span class="line">        SAVE_HOOK = <span class="keyword">this</span>;<span class="comment">//让一次gc复活</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>注意：之所以只能进行一次的原因是对象的两个状态已经改变了不能改变回来了</p>
<ol start="2">
<li>jdk内部一些包就是使用这中方法进行资源的释放的</li>
</ol>
<blockquote>
<p>覆盖finalize方法以确保资源释放</p>
</blockquote>
<p>作为一个补充操作，以防用户忘记“关闭“资源，JDK中FileInputStream、FileOutputStream、Connection类均用了此”技术“，下面代码摘自FileInputStream类</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Ensures that the &lt;code&gt;close&lt;/code&gt; method of this file input stream is</span></span><br><span class="line"><span class="comment"> * called when there are no more references to it.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@exception</span>  IOException  if an I/O error occurs.</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@see</span>        java.io.FileInputStream#close()</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">finalize</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> ((fd != <span class="keyword">null</span>) &amp;&amp;  (fd != FileDescriptor.in)) &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/*</span></span><br><span class="line"><span class="comment">         * Finalizer should not release the FileDescriptor if another</span></span><br><span class="line"><span class="comment">         * stream is still using it. If the user directly invokes</span></span><br><span class="line"><span class="comment">         * close() then the FileDescriptor is also released.</span></span><br><span class="line"><span class="comment">         */</span></span><br><span class="line">        runningFinalize.set(Boolean.TRUE);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            close();</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            runningFinalize.set(Boolean.FALSE);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
          
        
      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      

      

      
      
        <div class="post-eof"></div>
      
    </footer>
  </div>
  
  
  
  </article>


    
  </section>

  
  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/page/4/"><i class="fa fa-angle-left"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/4/">4</a><span class="page-number current">5</span><a class="page-number" href="/page/6/">6</a><span class="space">&hellip;</span><a class="page-number" href="/page/14/">14</a><a class="extend next" rel="next" href="/page/6/"><i class="fa fa-angle-right"></i></a>
  </nav>



          </div>
          


          

        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">kyssion</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">133</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                
                  <span class="site-state-item-count">3</span>
                  <span class="site-state-item-name">分类</span>
                
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                
                  <span class="site-state-item-count">2</span>
                  <span class="site-state-item-name">标签</span>
                
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2018</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">kyssion</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Mist</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  

  

  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
